package handler

import (
	"context"
	"crypto/md5"
	"fmt"
	"github.com/anaskhan96/go-password-encoder"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"gorm.io/gorm"
	"strings"
	"user_srv/model/mysql"
	"user_srv/user"
)

type UserService struct {
	user_pb.UnimplementedUserServer
}

func ModelToResponse(u mysql.User) user_pb.UserInfoResponse {
	userInfoResp := user_pb.UserInfoResponse{
		Id:       int32(u.ID),
		PassWord: u.Password,
		Mobile:   u.Mobile,
		NickName: u.NickName,
		BirthDay: uint64(u.BirthDay),
		Gender:   u.Gender,
		Role:     int32(u.Role),
	}
	return userInfoResp
}

// 注册用户
func (u *UserService) CreateUser(ctx context.Context, in *user_pb.CreateUserInfo) (*user_pb.UserInfoResponse, error) {
	//查询要注册的用户是否存在
	mobile, err := mysql.GetUserDetailByMobile(in.Mobile)

	if mobile.ID > 0 {
		return nil, status.Error(codes.Internal, "用户已存在")
	}

	//加密密码
	options := &password.Options{10, 10000, 50, md5.New}
	salt, encodedPwd := password.Encode(in.Password, options)

	passWord := fmt.Sprintf("$pbkd2_md5$%s$%s", salt, encodedPwd)

	//创建用户
	userInfo := mysql.User{
		Model:    gorm.Model{},
		Mobile:   in.Mobile,
		Password: passWord,
		NickName: in.NickName,
	}
	err = userInfo.RegisterUser()
	if err != nil {
		return nil, status.Error(codes.Internal, "注册失败")
	}
	response := ModelToResponse(userInfo)
	return &response, nil
}

// 检查密码是否正确
func (u *UserService) CheckPassWord(ctx context.Context, in *user_pb.PasswordCheckInfo) (*user_pb.CheckResponse, error) {
	options := &password.Options{10, 10000, 50, md5.New}

	//字符串分割
	split := strings.Split(in.EncryptedPassword, "$")

	check := password.Verify(in.Password, split[2], split[3], options)

	return &user_pb.CheckResponse{Success: check}, nil
}

// 查询用户列表
func (c *UserService) GetUserList(ctx context.Context, in *user_pb.PageInfo) (*user_pb.UserListResponse, error) {
	list, err, nums := mysql.GetUserList(int(in.Pn), int(in.PSize))
	if err != nil {
		return nil, status.Error(codes.Internal, "查询用户列表失败")
	}
	var user []*user_pb.UserInfoResponse

	for _, v := range list {
		user = append(user, &user_pb.UserInfoResponse{
			Id:       int32(v.ID),
			PassWord: v.NickName,
			Mobile:   v.Mobile,
			NickName: v.NickName,
			BirthDay: uint64(v.BirthDay),
			Gender:   v.Gender,
			Role:     int32(v.Role),
		})
	}

	return &user_pb.UserListResponse{
		Total: int32(nums),
		Data:  user,
	}, nil
}

// 根据手机号查询用户数据
func (c *UserService) GetUserByMobile(ctx context.Context, in *user_pb.MobileRequest) (*user_pb.UserInfoResponse, error) {
	mobile, err := mysql.GetUserDetailByMobile(in.Mobile)
	if err != nil {
		return nil, status.Error(codes.Internal, "查询用户失败")
	}
	return &user_pb.UserInfoResponse{
		Id:       int32(mobile.ID),
		PassWord: mobile.Password,
		Mobile:   mobile.Mobile,
		NickName: mobile.NickName,
		BirthDay: uint64(mobile.BirthDay),
		Gender:   mobile.Gender,
		Role:     int32(mobile.Role),
	}, nil
}

// 更新用户
func (c *UserService) UpdateUser(ctx context.Context, in *user_pb.UpdateUserInfo) (*user_pb.UserEmpty, error) {
	u := mysql.User{
		Model: gorm.Model{
			ID: uint(in.Id),
		},
		NickName: in.NickName,
		BirthDay: int64(in.BirthDay),
		Gender:   in.Gender,
	}
	err := mysql.UpdateUser(&u)
	if err != nil {
		return nil, status.Error(codes.Internal, "更新用户失败")
	}
	return nil, nil
}
